From b01229db4b1b4c0d0ea29f55be575da7dd57fda0 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 21 Feb 2014 22:08:00 -0500 Subject: [PATCH] Fix popover life-cycle handling c28784524016b2a8eac18d5046ebc8cdaca7f9b0 was trying to fix the memory leak caused by popovers begin destroyed in gtk_window_destroy before chaining up to gtk_widget_destroy, which unrealizes the window, and would clean up the popover windows if the popovers were still around. Fix this in a better way by moving the popover destruction after the chaining up, so we unrealize first, and then destroy the popovers. Also, make _gtk_window_remove_popover unrealize the popover, for symmetry with _gtk_window_add_popover. This should fix https://bugzilla.gnome.org/show_bug.cgi?id=724921 --- gtk/gtkwindow.c | 37 ++++++++++++++----------------------- 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index befca5ac85..d34e24c4ba 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -1338,18 +1338,8 @@ popover_destroy (GtkWindowPopover *popover) popover->unmap_id = 0; } - if (popover->widget) - { - GtkWidget *parent; - - parent = gtk_widget_get_parent (popover->widget); - - if (parent) - { - gtk_widget_unregister_window (parent, popover->window); - gtk_widget_unparent (popover->widget); - } - } + if (popover->widget && gtk_widget_get_parent (popover->widget)) + gtk_widget_unparent (popover->widget); if (popover->window) gdk_window_destroy (popover->window); @@ -2679,21 +2669,20 @@ gtk_window_dispose (GObject *object) GtkWindow *window = GTK_WINDOW (object); GtkWindowPrivate *priv = window->priv; - while (priv->popovers) - { - GtkWindowPopover *popover; - - popover = priv->popovers->data; - priv->popovers = g_list_delete_link (priv->popovers, priv->popovers); - popover_destroy (popover); - } - gtk_window_set_focus (window, NULL); gtk_window_set_default (window, NULL); unset_titlebar (window); remove_attach_widget (window); G_OBJECT_CLASS (gtk_window_parent_class)->dispose (object); + + while (priv->popovers) + { + GtkWindowPopover *popover = priv->popovers->data; + priv->popovers = g_list_delete_link (priv->popovers, priv->popovers); + popover_destroy (popover); + } + } static void @@ -5987,8 +5976,7 @@ popover_realize (GtkWidget *widget, attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL; parent_window = gtk_widget_get_window (GTK_WIDGET (window)); - popover->window = - gdk_window_new (parent_window, &attributes, attributes_mask); + popover->window = gdk_window_new (parent_window, &attributes, attributes_mask); gtk_widget_register_window (GTK_WIDGET (window), popover->window); gtk_widget_set_parent_window (popover->widget, popover->window); @@ -12212,6 +12200,9 @@ _gtk_window_remove_popover (GtkWindow *window, if (!data) return; + if (gtk_widget_get_realized (GTK_WIDGET (window))) + popover_unrealize (popover, data, window); + priv->popovers = g_list_remove (priv->popovers, data); popover_destroy (data); } -- 2.30.2